package org.jeecg.modules.saledetail;

import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Lottery {
   public static List<RewardItem> NORMAL_WEIGHT = new ArrayList<>();

    static {
        NORMAL_WEIGHT.add(new RewardItem("GRAND_PRIZE", 8000.0));
        NORMAL_WEIGHT.add(new RewardItem("ACTOR_OR_SKIN", 22000.0));
        NORMAL_WEIGHT.add(new RewardItem("SPECIAL_SHARD", 3430000.0));
        NORMAL_WEIGHT.add(new RewardItem("POSY", 4130000.0));
        NORMAL_WEIGHT.add(new RewardItem("DIAMOND", 1590000.0));
        NORMAL_WEIGHT.add(new RewardItem("ROSE", 600000.0));
        NORMAL_WEIGHT.add(new RewardItem("EFFECTS", 330000.0));
    }



    private static final int[][] POSY_WEIGHT = {
            {1600, 235},
            {400, 375},
            {80, 1878},
            {50, 7512}
    };

    private static final String[] SPECIAL_SHARD = {"SKIN_SHARD", "ACTOR_SHARD"};

    private static final Map<String, String> NAME = new HashMap<String, String>() {{
        put("GRAND_PRIZE", "荣耀水晶*1");
        put("DIAMOND", "钻石*50");
        put("ROSE", "浓情玫瑰*1");
        put("EFFECTS", "局内特效自选礼包*1");
        put("ACTOR1", "[英雄]花木兰*1");
        put("ACTOR2", "[英雄]钟馗*1");
        put("SKIN1", "[皮肤]偶像歌手*1");
        put("SKIN2", "[皮肤]幻想奇妙夜*1");
        put("SKIN_SHARD", "皮肤碎片*5");
        put("ACTOR_SHARD", "英雄碎片*5");
        put("POSY", "铭文碎片*");
    }};

    private static final int LUCK_ADD = 600;
    private static final double LUCK_DEL = LUCK_ADD / (NORMAL_WEIGHT.size() - 1);

    @Data
    public static class Result {
        private int posy;
        private int diamond;
        private int grandPrize;
        private int actorShard;
        private int skinShard;
        private int rose;
        private int effects;
        private int actor1;
        private int actor2;
        private int skin1;
        private int skin2;

        public void add(String reward) {
            for (Map.Entry<String, String> entry : NAME.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                if (reward.contains(key)) {
                    String plus = reward.equals(key) ? "1" : reward.replace("POSY", "");
                    plus = plus.matches("\\d+") ? plus : String.valueOf(getNumberFromString(value));
                    switch (key) {
                        case "GRAND_PRIZE":
                            grandPrize += Integer.parseInt(plus);
                            break;
                        case "DIAMOND":
                            diamond += Integer.parseInt(plus);
                            break;
                        case "ROSE":
                            rose += Integer.parseInt(plus);
                            break;
                        case "EFFECTS":
                            effects += Integer.parseInt(plus);
                            break;
                        case "ACTOR1":
                            actor1 += Integer.parseInt(plus);
                            break;
                        case "ACTOR2":
                            actor2 += Integer.parseInt(plus);
                            break;
                        case "SKIN1":
                            skin1 += Integer.parseInt(plus);
                            break;
                        case "SKIN2":
                            skin2 += Integer.parseInt(plus);
                            break;
                        case "SKIN_SHARD":
                            skinShard += Integer.parseInt(plus);
                            break;
                        case "ACTOR_SHARD":
                            actorShard += Integer.parseInt(plus);
                            break;
                        case "POSY":
                            posy += Integer.parseInt(plus);
                            break;
                    }
                    break;
                }
            }
        }
        public int getPosy() {
            return posy;
        }

        public int getDiamond() {
            return diamond;
        }

        public int getGrandPrize() {
            return grandPrize;
        }

        public int getActorShard() {
            return actorShard;
        }

        public int getSkinShard() {
            return skinShard;
        }

        public int getRose() {
            return rose;
        }

        public int getEffects() {
            return effects;
        }

        public int getActor1() {
            return actor1;
        }

        public int getActor2() {
            return actor2;
        }

        public int getSkin1() {
            return skin1;
        }

        public int getSkin2() {
            return skin2;
        }

        private int getNumberFromString(String str) {
            Pattern pattern = Pattern.compile("\\d+");
            Matcher matcher = pattern.matcher(str);
            if (matcher.find()) {
                return Integer.parseInt(matcher.group());
            }
            return 0;
        }
    }

    public static Result drawLottery(int count) {
        Result result = new Result();
        double luck = Math.random();
        double totalWeight = 0.0;
        List<RewardItem> weight = NORMAL_WEIGHT;

        for (RewardItem item : weight) {
            totalWeight += item.getWeight();
        }

        if (luck < 0.02) {
            result.add("GRAND_PRIZE");
            count--;
        } else if (luck < 0.06) {
            result.add("ACTOR_OR_SKIN");
            count--;
        }

        while (count > 0) {
            double random = Math.random() * totalWeight;
            for (RewardItem item : weight) {
                random -= item.getWeight();
                if (random <= 0) {
                    String reward = String.valueOf(item.getName());
                    if (reward.equals("SPECIAL_SHARD")) {
                        String specialShard = SPECIAL_SHARD[(int) (Math.random() * SPECIAL_SHARD.length)];
                        result.add(specialShard);
                    } else if (reward.equals("POSY")) {
                        int posyIndex = -1;
                        double posyRandom = Math.random();
                        for (int i = 0; i < POSY_WEIGHT.length; i++) {
                            posyRandom -= (double) POSY_WEIGHT[i][0] / 10000;
                            if (posyRandom <= 0) {
                                posyIndex = i;
                                break;
                            }
                        }
                        if (posyIndex != -1) {
                            int posyCount = POSY_WEIGHT[posyIndex][1];
                            result.add(reward + posyCount);
                        }
                    } else {
                        result.add(reward);
                    }
                    count--;
                    break;
                }
            }
        }

        // Apply luck factor
        if (luck >= 0.06) {
            double luckWeight = (luck - 0.06) / (1 - 0.06) * LUCK_DEL;
            for (RewardItem item : NORMAL_WEIGHT) {
                double weight1 = item.getWeight();
                weight1-= luckWeight;
                item.setWeight(weight1);
            }
        }

        return result;
    }

    public static void main(String[] args) {
        Result result = drawLottery(361);
        System.out.println("荣耀水晶");
        System.out.println(result);
    }}